package com.topsec.manager.service.impl;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.topsec.manager.common.CommonData;
import com.topsec.manager.common.Constants;
import com.topsec.manager.common.Model;
import com.topsec.manager.controller.req.CTCSVersionReq;
import com.topsec.manager.controller.req.DnsAndIp_TaskReq;
import com.topsec.manager.controller.req.Sys_RunState;
import com.topsec.manager.controller.req.Sys_Threshold;
import com.topsec.manager.controller.req.ToolReq;
import com.topsec.manager.controller.req.VersionReq;
import com.topsec.manager.dao.ReleaseMapper;
import com.topsec.manager.entity.AlarmBo;
import com.topsec.manager.entity.CHelloBean;
import com.topsec.manager.entity.CHelloExtensionVO;
import com.topsec.manager.entity.CHelloQueryVO;
import com.topsec.manager.entity.Ctresource;
import com.topsec.manager.entity.ExtensionVO;
import com.topsec.manager.entity.FindTaskBo;
import com.topsec.manager.entity.HttpXyBean;
import com.topsec.manager.entity.SslCertBean;
import com.topsec.manager.entity.SslCertQueryVO;
import com.topsec.manager.entity.SslCertRuleVO;
import com.topsec.manager.entity.SystemLogger;
import com.topsec.manager.entity.Task_DnsVo;
import com.topsec.manager.entity.ToolBo;
import com.topsec.manager.entity.ToolTestBean;
import com.topsec.manager.entity.VersionVo;
import com.topsec.manager.service.ReleaseServiceInter;
import com.topsec.manager.util.CmdExecutor;
import com.topsec.manager.util.JsonUtil;
import com.topsec.manager.vo.HttpxyRuleVO;
import com.topsec.manager.vo.HttpxyVO;

/**
 * @author zhaoys
 * @date 2017年7月22日 下午3:48:46
 */

@Service("releaseService")
@Transactional
public class ReleaseServiceImpl implements ReleaseServiceInter {
	// 日志记录器
	private final Logger log = LoggerFactory.getLogger(this.getClass());
	@Autowired
	private ReleaseMapper releaseMapper;
	SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	@Override
	public List<VersionVo> findVersionByid(String id) {
		String[] split = id.split("#");
		List<VersionVo> l = new ArrayList<VersionVo>();
		for (int i = 0; i < split.length; i++) {
			VersionVo v = new VersionVo();
			v.setId(Long.valueOf(split[i]));
			l.add(v);
		}
		List<VersionVo> list = releaseMapper.findVersionByid(l);
		return list;
	}

	@Override
	public List<ToolBo> findToolByid(String id) {
		String[] split = id.split("#");
		List<ToolBo> l = new ArrayList<ToolBo>();
		for (int i = 0; i < split.length; i++) {
			ToolBo t = new ToolBo();
			t.setId(Long.valueOf(split[i]));
			l.add(t);
		}
		List<ToolBo> list = releaseMapper.findToolByid(l);
		return list;
	}

	@Override
	public String checkToolsRepeat(List<ToolReq> toolList) {
		List<String> resultList = new ArrayList<>();
		for (ToolReq req : toolList) {
			List<ToolReq> toolReqs = releaseMapper.checkTools(req);
			if (toolReqs.size() > 0) {
				resultList.add("success");
			} else {
				resultList.add("error");
			}
		}
		return JsonUtil.json(resultList);
	}

	public List<VersionVo> findVersion(VersionReq v) {
		List<VersionVo> list = releaseMapper.findversion(v);
		return list;
	}

	@Override
	public List<ToolBo> findTool() {
		List<ToolBo> list = releaseMapper.findtool();
		return list;
	}

	@Override
	public List<ToolBo> findTool1() {
		List<ToolBo> list = releaseMapper.findtool1();
		return list;
	}

	@Override
	public List<CHelloQueryVO> getChelloData(String s) {
		String resutl = "";
		Gson gson = new Gson();
		List<CHelloBean> cHelloBeanList = releaseMapper.getChelloData(s);
		List<CHelloQueryVO> cHelloBeanVOList = new ArrayList<>();
		for (CHelloBean sslCertDatum : cHelloBeanList) {
			CHelloQueryVO cHelloVO = new CHelloQueryVO();

			cHelloVO.setConfId(sslCertDatum.getConfId());
			cHelloVO.setGroupId(sslCertDatum.getGroupId());
			cHelloVO.setToolType(sslCertDatum.getToolId());
			cHelloVO.setClipherSuite(sslCertDatum.getClipherSuite());
			cHelloVO.setExtensionLen(sslCertDatum.getExtensionLen());

			String ext = sslCertDatum.getExt();
			if (StringUtils.isNotEmpty(ext)) {
				List<ExtensionVO> extensionVOList = gson.fromJson(ext,
						new TypeToken<List<ExtensionVO>>() {
						}.getType());
				List<CHelloExtensionVO> cHelloExtensionVOList = new ArrayList<>();
				for (ExtensionVO extensionVO : extensionVOList) {
					CHelloExtensionVO cHelloExtensionVO = new CHelloExtensionVO();
					cHelloExtensionVO.setEncode(extensionVO.getEncode());
					cHelloExtensionVO.setMatchType(extensionVO.getMathType());
					cHelloExtensionVO.setType(extensionVO.getType());
					cHelloExtensionVO.setValue(extensionVO.getValue());
					cHelloExtensionVOList.add(cHelloExtensionVO);
				}
				cHelloVO.setExtension(cHelloExtensionVOList);
			}
			cHelloBeanVOList.add(cHelloVO);
		}
		return cHelloBeanVOList;
	}

	@Override
	public List<HttpxyVO> getHttpXyData(String s) {
		String resutl = "";
		Gson gson = new Gson();
		List<HttpXyBean> sslCertData = releaseMapper.getHttpXyData(s);
		List<HttpxyVO> httpxyVOList = new ArrayList<>();
		for (HttpXyBean sslCertDatum : sslCertData) {
			HttpxyVO httpxyVO = new HttpxyVO();

			httpxyVO.setConfig_id(sslCertDatum.getGroupName());
			httpxyVO.setTooltype(sslCertDatum.getToolId());

			String ext = sslCertDatum.getExt();
			List<HttpxyRuleVO> httpxyRuleVOList = new ArrayList<>();
			if (StringUtils.isNotEmpty(ext)) {
				List<HttpXyBean> httpXyBeanList = gson.fromJson(ext,
						new TypeToken<List<HttpXyBean>>() {
						}.getType());
				HttpxyRuleVO ruleVO = new HttpxyRuleVO();
				for (HttpXyBean httpXyBean : httpXyBeanList) {
					ruleVO.setMatch_value(httpXyBean.getMatchValue());
					ruleVO.setMatch_type(httpXyBean.getPpType());
					ruleVO.setHeader(httpXyBean.getHeader());
					ruleVO.setCase_sensitive(httpXyBean.getCaseSensitive());
					httpxyRuleVOList.add(ruleVO);
				}
			}
			httpxyVO.setRule(httpxyRuleVOList);
			httpxyVOList.add(httpxyVO);
		}
		return httpxyVOList;
	}

	@Override
	public List<SslCertQueryVO> getSslCertData(String s) {
		Gson gson = new Gson();
		List<SslCertQueryVO> sslCertQueryVOS = new ArrayList<>();
		List<SslCertBean> sslCertData = releaseMapper.getSslCertData(s);
		for (SslCertBean sslCertDatum : sslCertData) {
			SslCertQueryVO sslCertQueryVO = new SslCertQueryVO();
			sslCertQueryVO.setConfId(sslCertDatum.getConfigId());
			sslCertQueryVO.setGroupId(sslCertDatum.getGroupId());
			sslCertQueryVO.setTooltype(sslCertDatum.getToolId());
			String ext = sslCertDatum.getExt();
			if (StringUtils.isNotEmpty(ext)) {
				List<SslCertBean> extensionVOList = gson.fromJson(ext,
						new TypeToken<List<SslCertBean>>() {
						}.getType());
				List<SslCertRuleVO> sslCertRuleVOList = new ArrayList<>();
				for (SslCertBean sslCertBean : extensionVOList) {
					SslCertRuleVO sslCertRuleVO = new SslCertRuleVO();
					sslCertRuleVO.setEncode(sslCertBean.getEncode());
					sslCertRuleVO.setKey(sslCertBean.getRuleMonitor());
					sslCertRuleVO.setValue(sslCertBean.getMonitorContent());
					sslCertRuleVO.setMatchType(sslCertBean.getMathType());
					sslCertRuleVOList.add(sslCertRuleVO);
				}
				sslCertQueryVO.setSslCertRuleVOList(sslCertRuleVOList);
			}
			sslCertQueryVOS.add(sslCertQueryVO);
		}

		return sslCertQueryVOS;
	}
	/**
	 * copy file
	 * @param sourceFile
	 * @param targetFile
	 */
	private static void copyFile(File sourceFile, File targetFile){
		try {
			FileInputStream input = new FileInputStream(sourceFile);
			BufferedInputStream inBuff = new BufferedInputStream(input);
			FileOutputStream output = new FileOutputStream(targetFile);
			BufferedOutputStream outBuff = new BufferedOutputStream(output);
			byte[] b = new byte[1024 * 5];
			int len;
			while ((len = inBuff.read(b)) != -1) {
				outBuff.write(b, 0, len);
			}
			outBuff.flush();
			inBuff.close();
			outBuff.close();
			output.close();
			input.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	private String RZX = "/home/tool/rzx";
	private String BY = "/home/tool/by";
	private String JSS = "/home/tool/jss";
	private String FZ = "/home/tool/fz";
//	private String TOMCATPATH = "/workspacetopsec/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/topsec-web/WEB-INF/classes/static/images/tool/";
	private String TOMCATPATH = "/topsec/web/tomcat/webapps/topsec-web/WEB-INF/classes/static/images/tool/";
	@Override
	public boolean saveTool(ToolReq t) {
		log.info("发现新工具[" + t.getToolname() + "]");
		boolean result = true;
		SystemLogger s = null;
		String sfile = "";
		String efile = "";
		String suffix = "";
		String fn = "../../images/tool/";
		try {
			long currentTimeMillis = System.currentTimeMillis();
			String icopath = t.getIcopath();
			String[] split = icopath.split("\\.");
			if(split.length > 0){
				suffix = split[split.length-1];
				if("1".equals(t.getDeveloper())){
					sfile = BY + icopath;
				}else if("2".equals(t.getDeveloper())){
					sfile = RZX + icopath;
				}else if("3".equals(t.getDeveloper())){
					sfile = JSS + icopath;
				}else if("4".equals(t.getDeveloper())){
					sfile = FZ + icopath;
				}
				fn = fn + currentTimeMillis + "." +suffix;
				efile = TOMCATPATH + fn;
				File file = new File(sfile);
				if(file.isFile()){
					copyFile(file, new File(efile));
					t.setIcoshow(fn);
				}else{
					t.setIcoshow(icopath);
				}
			}
			t.setCommitTime(sf.format(new Date()));
			releaseMapper.saveTool(t);
			List<FindTaskBo> list = releaseMapper.findTaskByurl(t.getUrl());
			for (int i = 0; i < list.size(); i++) {
				FindTaskBo findTaskBo = list.get(i);
				releaseMapper.updateStatus(t.getUrl());
			}
			String info = "【" + sf.format(new Date()) + "】" + "发现新工具【工具名称："
					+ t.getToolname() + "||发现者：" + t.getDeveloper() + "】入库成功";
			s = new SystemLogger("info", Model.getName(1), info,
					sf.format(new Date()), t.getId());
		} catch (Exception e) {
			result = false;
			String info = "【" + sf.format(new Date()) + "】" + "发现新工具【工具名称："
					+ t.getToolname() + "||发现者：" + t.getDeveloper()
					+ "】入库失败.异常信息";
			s = new SystemLogger("error", Model.getName(1), info,
					sf.format(new Date()), t.getId());
			log.info("工具[" + t.getToolname() + "]入库失败：" + e.getMessage());
			e.printStackTrace();
		}
		log.info("新工具[" + t.getToolname() + "]成功");
		releaseMapper.saveLogger(s);
		return result;
	}

	@Override
	public void versionFollowing(ToolReq v) {
		try {
			// 将数据以流的方式写入文件中
			ObjectOutputStream dot = new ObjectOutputStream(
					new FileOutputStream(Constants.W_S_REQUEST + "f_tool_"
							+ System.currentTimeMillis() + ".f"));
			dot.writeObject(v);
			dot.close();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	@Override
	public void versionFollowings(List<ToolReq> vL) {
		try {
			// 将数据以流的方式写入文件中
			ObjectOutputStream dot = new ObjectOutputStream(
					new FileOutputStream(Constants.W_S_REQUEST + "f_tool_"
							+ System.currentTimeMillis() + ".f"));
			dot.writeObject(vL);
			dot.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public void saveTVersion(VersionReq v) {
		SystemLogger s = null;
		log.info("工具[" + v.getToolid() + "]发现新版本[" + v.getVersionnumber() + "]");
		String info = "";
		String fpath = "/home/tool/";
		try {
			v.setCommittime(sf.format(new Date()));
			List<VersionReq> findVersion = releaseMapper.findVersion(v);
			if (findVersion.size() > 0) {
				info = "【" + sf.format(new Date()) + "】版本号为【"
						+ v.getVersionnumber() + "】工具id为【" + v.getToolid()
						+ "】的版本更新样本路径或者图标路径成功.";
				if (v.getIcopath() != null && !"".equals(v.getIcopath())) {
					if ("2".equals(v.getDeveloper())) {// 任子行
						fpath = fpath + "ty" + v.getIcopath();
					}
					long currentTimeMillis = System.currentTimeMillis();
					File f = new File(fpath);
					String filename = "";
					if (f.isFile()) {
						String samplepath = v.getIcopath();
						filename = currentTimeMillis
								+ samplepath.substring(
										samplepath.lastIndexOf("."),
										samplepath.length());
						CmdExecutor.exec("cp " + fpath + " /home/data/"
								+ filename);
					}
					v.setIcoshowpath("../../images/tool/" + filename);
					// 更新页面工具图标显示为最新
					releaseMapper.updatTool(v);
				}
				releaseMapper.upVersion(v);
			} else {
				info = "【" + sf.format(new Date()) + "】最新发现版本号为【"
						+ v.getVersionnumber() + "】工具id为【" + v.getToolid()
						+ "】的版本入库成功.";
				releaseMapper.saveTversion(v);
			}
			s = new SystemLogger("info", Model.getName(2), info,
					sf.format(new Date()), v.getToolid());

		} catch (Exception e) {
			e.printStackTrace();
			log.info("工具[" + v.getToolid() + "]新版本[" + v.getVersionnumber()
					+ "]入库失败：" + e.getMessage());
			info = "【" + sf.format(new Date()) + "】版本号为【"
					+ v.getVersionnumber() + "】工具id为【" + v.getToolid()
					+ "】的入库失败,失败信息：" + e.getMessage().toString();
			s = new SystemLogger("error", Model.getName(2), info,
					sf.format(new Date()), v.getToolid());
		}
		log.info("工具[" + v.getToolid() + "]新版本[" + v.getVersionnumber()
				+ "]入库成功");
		releaseMapper.saveLogger(s);
	}

	// 初始化
	private void init() {

		try {
			// 查出所有阈值表中的信息
			List<Sys_Threshold> thresholdS = releaseMapper.findmsg();
			// 放入map中
			for (int i = 0; i < thresholdS.size(); i++) {
				if (thresholdS.get(i) != null) {
					CommonData.alarmmap.put(thresholdS.get(i).getIp(),
							thresholdS.get(i));
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public void saveDeviceInfo(Sys_RunState deviceInfo) {
		// 初始化
		init();
		Map<String, Sys_Threshold> map = CommonData.alarmmap;
		AlarmBo alarmbo = new AlarmBo();
		alarmbo.setLevel("1");// 级别
		alarmbo.setTtaskid(1);// 任务id
		alarmbo.setStatus("1");// 状态
		alarmbo.setDatanum("1");
		String msg = "";
		// 如果阈值表中有此ip
		if (map.containsKey(deviceInfo.getIp())) {
			// 以ip为key得到值
			Sys_Threshold sr = map.get(deviceInfo.getIp());
			// 开始判断
			String cpu = sr.getCPU();
			if (cpu != null) {
				if (Integer.parseInt(deviceInfo.getCpu()) > Integer
						.parseInt(cpu)) {
					alarmbo.setModule("IP监视");
					msg = msg + "deviceInfo.getIp()" + "cpu过高";
					alarmbo.setDescr(msg);
					// 插入报警信息
					releaseMapper.savealarm(alarmbo);
				}
			}
			String disk = sr.getDisk();
			if (disk != null) {
				if (Integer.parseInt(deviceInfo.getDisk()) > Integer
						.parseInt(disk)) {
					alarmbo.setModule("URL");
					msg = msg + "deviceInfo.getIp()" + "磁盘空间不足";
					alarmbo.setDescr(msg);
					// 插入报警信息
					releaseMapper.savealarm(alarmbo);
				}
			}
			String memory = sr.getMemory();
			if (memory != null) {
				if (Integer.parseInt(deviceInfo.getMemory()) > Integer
						.parseInt(memory)) {
					alarmbo.setModule("IP控管");
					msg = msg + "deviceInfo.getIp()" + "内存不足";
					alarmbo.setDescr(msg);
					// 插入报警信息
					releaseMapper.savealarm(alarmbo);
				}
			}
		} else {
			// 插入运行信息
			releaseMapper.saveDeviceInfo(deviceInfo);
		}
	}

	@Override
	public void saveCtresource(Ctresource c) {
		c.setCommittime(new Date());
		releaseMapper.saveCtresource(c);
	}

	@Override
	public void saveToolTest(ToolTestBean t) {
		t.setCommitTime(new Date());
		t.setCsTime(new Date());
		releaseMapper.saveToolTest(t);
	}

	/**
	 * 保存版本穿透测试指令到send文件夹中
	 *
	 * @param sendct
	 */
	@Override
	public void saveSendVersionTest(List<CTCSVersionReq> sendct) {
		try {
			// 将数据以流的方式写入文件中
			ObjectOutputStream dot = new ObjectOutputStream(
					new FileOutputStream(Constants.W_S_REQUEST
							+ "send_ctcs_version_" + System.currentTimeMillis()
							+ ".ct"));
			dot.writeObject(sendct);
			dot.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 外网请求接V生成版本穿透测试指令
	 *
	 * @param resct
	 */
	/**
	 * 外网请求接V生成版本穿透测试指令
	 *
	 * @param resct
	 */
	@Override
	public void saveResVersionTest(List<CTCSVersionReq> resct) {
		try {
			// 将数据以流的方式写入文件中
			ObjectOutputStream dot = new ObjectOutputStream(
					new FileOutputStream(Constants.W_S_REQUEST
							+ "res_ctcs_version_" + System.currentTimeMillis()
							+ ".ct"));
			dot.writeObject(resct);
			dot.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public int upXinDnsTask(DnsAndIp_TaskReq dReq) {
		// TODO Auto-generated method stub
		int re = releaseMapper.upXinDnsTaskStutas(dReq);
		return re;
	}

	@Override
	public int upTianDnsTask(DnsAndIp_TaskReq dReq) {
		// TODO Auto-generated method stub
		int re = releaseMapper.upTiannDnsTaskStutas(dReq);
		return re;
	}

	@Override
	public Task_DnsVo findDnsById(long id) {
		Task_DnsVo dnsById = releaseMapper.findDnsById(id);
		return dnsById;
	}

	@Override
	public void saveLogger(SystemLogger log) {
		releaseMapper.saveLogger(log);

	}

}
